package com.ds.infrastructure.hyperspace.container.internal.gzs;

import com.ds.infrastructure.hyperspace.container.flow.context.HyperspaceDuplexFlowContext;
import com.ds.infrastructure.zonesdk.Zone;
import com.ds.infrastructure.zonesdk.ZoneChangeListener;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author  Weishaoying
 */
@Slf4j
@Getter
public class GzsChangeContextListener {

    private final Map<String, HyperspaceDuplexFlowContext> duplexFlowContexts;

    private final ZoneChangeListener sdkZoneChangeListener;

    public GzsChangeContextListener() {
        this.sdkZoneChangeListener = new DefaultZoneChangeListener();
        this.duplexFlowContexts = new ConcurrentHashMap<>();
    }

    public void addContext(HyperspaceDuplexFlowContext context) {
        duplexFlowContexts.put(context.getRequestId(), context);
    }

    public void removeContext(HyperspaceDuplexFlowContext context) {
        duplexFlowContexts.remove(context.getRequestId());
    }

    public boolean isEmpty() {
        return duplexFlowContexts == null || duplexFlowContexts.isEmpty();
    }

    class DefaultZoneChangeListener implements ZoneChangeListener {

        @Override
        public void onChange(Zone from, Zone to) {
            try {
                if (from == to || CollectionUtils.isEmpty(duplexFlowContexts)) {
                    return;
                }
                String oldZoneId = "";
                Zone.ZoneStatus oldZoneStatus = null;
                if (from != null) {
                    oldZoneId = from.getZoneId();
                    oldZoneStatus = from.getStatus();
                }
                String nowZoneId = "";
                Zone.ZoneStatus newZoneStatus = null;
                if (to != null) {
                    nowZoneId = to.getZoneId();
                    newZoneStatus = to.getStatus();
                }
                if (oldZoneId.equals(nowZoneId) && oldZoneStatus == newZoneStatus) {
                    return;
                }

                Iterator<Map.Entry<String,HyperspaceDuplexFlowContext>> duplexFlowContextIterator =
                        duplexFlowContexts.entrySet().iterator();
                while (duplexFlowContextIterator.hasNext()) {
                    Map.Entry<String,HyperspaceDuplexFlowContext> duplexFlowContextEntry =
                            duplexFlowContextIterator.next();
                    duplexFlowContextEntry.getValue().getEntryProtocolAdapter().closeEntryChannel();
                }
            } catch (Exception e) {
                log.error("Notify gzs status change failed!", e);
            }
        }
    }
}
